﻿// // ******************************************************************
// //       /\ /|       @file       SystemQueryHandler.cs
// //       \ V/        @brief      await29
// //       | "")       @author     Await, 285283010@qq.com
// //       /  |
// //      /  \\        @Modified   2025-02-20 20:02
// //    *(__\_\        @Copyright  Copyright (c) , 2025-02-06 20:02 Await
// // ******************************************************************

using AutomaticSubtitles.Contracts.Dto;
using AutomaticSubtitles.Service.Application.System.Queries;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using AutomaticSubtitles.Contracts.Vo;
using Newtonsoft.Json;
using Serilog.Events;
using System.Reflection;

namespace AutomaticSubtitles.Service.Application.System;

public class SystemQueryHandler
{
    private readonly string _logPath;

    public SystemQueryHandler()
    {
        // 获取应用程序的基础目录
        //var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
        var baseDirectory = Directory.GetCurrentDirectory();
        _logPath = Path.Combine(baseDirectory, ".cache", "logs");

        // 确保日志目录存在
        if (!Directory.Exists(_logPath)) Directory.CreateDirectory(_logPath);
    }

    [EventHandler]
    public async Task Handle(GetSystemListQuery query)
    {
        var result = new SystemLogDto();
        var logFiles = Directory.GetFiles(_logPath, "log*.txt")
            .OrderByDescending(f => f)
            .ToList();

        var logEntries = new List<LogEntryDto>();
        var startTime = query.data.startTime.HasValue ? DateTimeOffset.FromUnixTimeSeconds(query.data.startTime.Value).DateTime : DateTime.MinValue;
        var endTime = query.data.endTime.HasValue ? DateTimeOffset.FromUnixTimeSeconds(query.data.endTime.Value).DateTime : DateTime.MaxValue;

        foreach (var file in logFiles)
            try
            {
                using var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                using var reader = new StreamReader(fileStream);
                string? line;
                while ((line = await reader.ReadLineAsync()) != null)
                    try
                    {
                        var logEvent = JsonConvert.DeserializeObject<Dictionary<string, object>>(line);
                        if (logEvent == null) continue;

                        // 解析时间戳
                        var timestamp = DateTime.Parse(logEvent["@t"].ToString()!);
                        if (timestamp < startTime || timestamp > endTime) continue;

                        // 解析日志级别
                        var level = logEvent.ContainsKey("@l") ? logEvent["@l"].ToString() : "Information";
                        if (query.data.levels != null && !query.data.levels.Contains(level)) continue;

                        // 解析消息
                        var message = logEvent["@mt"].ToString();
                        if (!string.IsNullOrEmpty(query.data.keyword) &&
                            !message.Contains(query.data.keyword, StringComparison.OrdinalIgnoreCase)) continue;

                        var entry = new LogEntryDto
                        {
                            Timestamp = timestamp.ToString("o"),
                            Level = level ?? "Information",
                            Message = message ?? string.Empty,
                            SourceContext = logEvent.ContainsKey("SourceContext") ? logEvent["SourceContext"].ToString() ?? string.Empty : string.Empty,
                            Properties = new Dictionary<string, string>()
                        };

                        // 添加其他属性
                        foreach (var kvp in logEvent)
                            if (!kvp.Key.StartsWith("@") && kvp.Key != "SourceContext")
                                entry.Properties[kvp.Key] = kvp.Value?.ToString() ?? string.Empty;

                        logEntries.Add(entry);
                    }
                    catch
                    {
                        // 忽略解析错误的日志行
                        continue;
                    }
            }
            catch (IOException)
            {
                // 如果文件访问出错，跳过该文件
                continue;
            }

        // 排序
        if (!string.IsNullOrEmpty(query.data.sortField))
            logEntries = query.data.sortOrder?.ToLower() == "desc"
                ? logEntries.OrderByDescending(e => GetPropertyValue(e, query.data.sortField)).ToList()
                : logEntries.OrderBy(e => GetPropertyValue(e, query.data.sortField)).ToList();
        else
            logEntries = logEntries.OrderByDescending(e => DateTime.Parse(e.Timestamp)).ToList();

        // 分页
        var pageSize = query.data.pageSize ?? 20;
        var pageIndex = query.data.pageIndex ?? 1;
        var skip = (pageIndex - 1) * pageSize;

        result.Total = logEntries.Count;
        result.Items = logEntries.Skip(skip).Take(pageSize).ToList();

        query.Result = result;
    }

    private string GetPropertyValue(LogEntryDto entry, string propertyName)
    {
        return propertyName.ToLower() switch
        {
            "timestamp"     => entry.Timestamp,
            "level"         => entry.Level,
            "message"       => entry.Message,
            "sourcecontext" => entry.SourceContext,
            _               => entry.Properties.ContainsKey(propertyName) ? entry.Properties[propertyName] : string.Empty
        };
    }
}